/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.util.Arrays;

class Obj {
    public double value = 0;
    Obj(double value) {
        this.value = value;
    }
}
class PointerParalessCall {
    public static Obj[] GenerateFakeRandomObject() {
        Obj[] resource = new Obj[15];
        Arrays.fill(resource, new Obj(0));
        for (int i = 0; i < 15; i++) {
            double random = Math.random() * (10) + 1;
            resource[i] = new Obj(random);
        }
        return resource;
    }

    public static int global_value = 0;
    public static int[] GenerateFakeRandomInteger() {
        int[] resource = {12, 43, 56, 76, 89, 54, 45, 32, 35, 47, 46, 44, 21, 37, 84};
        return resource;
    }

    public int[] arr =  GenerateFakeRandomInteger();
    /***** Without parameters *****/

    /***************** No parameters *****************/
    public static Obj ParameterlessFoo() {
        Obj[] res = {new Obj(0), new Obj(0), new Obj(0), new Obj(0), new Obj(0)};
        Obj[] resources =GenerateFakeRandomObject();
        for (int i = 0; i < 200; i++) {
            res[i % 5] = resources[i % 15];
        }
        return res[1];
    }

    public static Obj CallParameterlessFoo(Supplier<Obj> f) {
        return f.apply();
    }

    public static double RunParameterlessFunctionPtr() {
        int count = 10000;
        global_value = 0;
        Obj i3 = new Obj(1);
        double startTime = System.nanoTime();
        for (int i = 0; i < count; i++) {
            i3 = CallParameterlessFoo(PointerParalessCall::ParameterlessFoo);
        }
        double midTime = System.nanoTime();
        for (int i = 0; i < count; i++) {
        }
        double endTime = System.nanoTime();
        double time = ((midTime - startTime) - (endTime - midTime)) / 1000000;
        System.out.println("res: " + i3);
        System.out.println("Function Call - RunParameterlessFunctionPtr:\t"+time+"ms");
        return time;
    }
}

class Benchmark {
    public static void main(String[] args) {
        PointerParalessCall.RunParameterlessFunctionPtr();
        // System.out.println("Ts Method Call Is End, global_value value: \t"+global_value);
    }
}

@FunctionalInterface
interface Supplier<R> {
    R apply();
}